package app.utils;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;

import java.io.IOException;
import java.io.Writer;
import java.util.List;

/**
 * Utils - JSON
 * 
 */
public final class JsonUtils {

	private static Log logger = LogFactory.getLog(JsonUtils.class);

	/** ObjectMapper */
	// private static ObjectMapper mapper = new ObjectMapper()
	// .setSerializationInclusion(Include.NON_NULL);
	private static ObjectMapper mapper = new ObjectMapper()
			.setSerializationInclusion(Include.NON_NULL).enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
			.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

	private static ObjectMapper mapperAll = new ObjectMapper()
			.setSerializationInclusion(Include.ALWAYS).enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
			.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

	/**
	 * 不可实例化
	 */
	private JsonUtils() {

		// mapper.setSerializationInclusion(Include.NON_NULL);
	}

	/**
	 * 将对象转换为JSON字符串
	 * 
	 * @param value
	 *            对象
	 * @return JSOn字符串
	 */
	public static String toJson(Object value) {
		try {
			return mapper.writeValueAsString(value);
		} catch (Exception e) {
			logger.error("ERROR:", e);
		}
		return null;
	}
	public static String toJsonAll(Object value) {
		try {
			return mapperAll.writeValueAsString(value);
		} catch (Exception e) {
			logger.error("ERROR:", e);
		}
		return null;
	}

	/**
	 * 将JSON字符串转换为对象
	 * 
	 * @param json
	 *            JSON字符串
	 * @param valueType
	 *            对象类型
	 * @return 对象
	 */
	public static <T> T toObject(String json, Class<T> valueType) {
		Assert.hasText(json);
		Assert.notNull(valueType);
		try {
			return mapper.readValue(json, valueType);
		} catch (Exception e) {
			logger.error("ERROR:", e);
		}
		return null;
	}

	/**
	 * 将JSON字符串转换为对象数组
	 * @param json
	 * JSON字符串
	 * @param valueType
	 *            对象类型
	 * @return 对象
	 */
	public static <T> List<T> toObjectList(String json, Class<T> valueType) {
		Assert.hasText(json);
		Assert.notNull(valueType);
		try {
			return mapper.readValue(json, new TypeReference<List<T>>() { });
		} catch (Exception e) {
			logger.error("ERROR:", e);
		}
		return null;
	}

	/**
	 * 将JSON字符串转换为对象
	 * 
	 * @param json
	 *            JSON字符串
	 * @param typeReference
	 *            对象类型
	 * @return 对象
	 */
	public static <T> T toObject(String json, TypeReference<T> typeReference) {
		Assert.hasText(json);
		Assert.notNull(typeReference);
		try {
			return mapper.readValue(json, typeReference);
		} catch (Exception e) {
			logger.error("ERROR:", e);
		}
		return null;
	}

	/**
	 * 将JSON字符串转换为对象
	 * 
	 * @param json
	 *            JSON字符串
	 * @param javaType
	 *            对象类型
	 * @return 对象
	 */
	public static <T> T toObject(String json, JavaType javaType) {
		Assert.hasText(json);
		Assert.notNull(javaType);
		try {
			return mapper.readValue(json, javaType);
		} catch (Exception e) {
			logger.error("ERROR:", e);
		}
		return null;
	}

	/**
	 * 将对象转换为JSON流
	 * 
	 * @param writer
	 *            writer
	 * @param value
	 *            对象
	 */
	public static void writeValue(Writer writer, Object value) {
		try {
			mapper.writeValue(writer, value);
		} catch (JsonGenerationException e) {
			logger.error("ERROR:", e);
		} catch (JsonMappingException e) {
			logger.error("ERROR:", e);
		} catch (IOException e) {
			logger.error("ERROR:", e);
		}
	}

	public static JavaType getCollectionType(Class<?> collectionClass,
                                             Class<?>... elementClasses) {
		return mapper.getTypeFactory().constructParametricType(collectionClass,
				elementClasses);
	}

}
